<template>
  <div ref="parentContainer" class="parent-container">
    <div
      class="draggable"
      :class="{ dragging: isDragging }"
      :style="{ left: position.x + 'px', top: position.y + 'px' }"
    >
      <div
        class="cursor-move"
        @mousedown="startDrag"
        @touchstart="startDrag"
      >
        ⋮ 拖拽手柄
      </div>
      <div class="content cursor-auto">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { reactive, ref, onUnmounted, onMounted } from 'vue';

  interface Position {
    x: number;
    y: number;
  }

  const position = reactive<Position>({
    x: 0,
    y: 0,
  });

  const startX = ref(0);
  const startY = ref(0);
  const parentContainer = ref<HTMLElement | null>(null);

  const isDragging = ref(false);

  // 添加防抖函数
  const debounce = (fn: Function, delay: number) => {
    let timer: number | null = null;
    return (...args: any[]) => {
      if (timer) window.cancelAnimationFrame(timer);
      timer = window.requestAnimationFrame(() => fn(...args));
    };
  };

  const startDrag = (e: MouseEvent | TouchEvent) => {
    isDragging.value = true;
    const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;

    startX.value = clientX - position.x;
    startY.value = clientY - position.y;

    // 添加全局事件监听
    document.addEventListener('mousemove', handleDrag);
    document.addEventListener('touchmove', handleDrag);
    document.addEventListener('mouseup', handleDragEnd);
    document.addEventListener('touchend', handleDragEnd);

    e.preventDefault();
  };

  // 使用防抖处理拖动事件
  const handleDrag = debounce((e: MouseEvent | TouchEvent) => {
    if (!isDragging.value) return;

    const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;

    position.x = clientX - startX.value;
    position.y = clientY - startY.value;

    // 边界处理
    position.x = Math.max(0, Math.min(window.innerWidth - 100, position.x));
    position.y = Math.max(0, Math.min(window.innerHeight - 100, position.y));
  }, 16);

  const handleDragEnd = () => {
    isDragging.value = false;
    // 移除全局事件监听
    document.removeEventListener('mousemove', handleDrag);
    document.removeEventListener('touchmove', handleDrag);
    document.removeEventListener('mouseup', handleDragEnd);
    document.removeEventListener('touchend', handleDragEnd);
  };

  onMounted(() => {
    if (parentContainer.value) {
      const rect = parentContainer.value.getBoundingClientRect();
      // 设置初始位置为父容器左上角
      position.x = rect.left;
      position.y = rect.top;

      // 若需要相对父容器内部定位（示例：居中）
      // position.x = (rect.width - 100) / 2; // 100是组件宽度
      // position.y = (rect.height - 100) / 2; // 100是组件高度
    }
  });

  // 组件卸载时清理事件监听
  onUnmounted(() => {
    handleDragEnd();
  });
</script>

<style>
  .draggable {
    position: absolute;
    min-width: 100px;
    min-height: 100px;
    background: #42b983;
    cursor: grab;
    z-index: 999;
  }
</style>
